<script setup lang="ts">
import { ref, nextTick } from "vue";
import { warning } from "@/message/messageApi";
import { marked } from "marked";

// 定义消息类型
interface ChatMessage {
  role: string;
  content: string;
  isThinking?: boolean; // 新增思考状态
}

// 响应式变量
const inputValue = ref('');
const messageHistory = ref<ChatMessage[]>([]);
const isSending = ref(false);
const memoryId = ref(generateConversationId());
const isShow = ref(true);

function generateConversationId() {
  return Date.now().toString() + Math.random().toString(36).substring(2);
};

// 发送消息函数
async function sendMessage() {
  if (!inputValue.value.trim()) {
    warning("请输入内容");
    return;
  }

  isShow.value = false;

  if (isSending.value) {
    warning("正在处理上一条消息，请稍候...");
    return;
  }

  isSending.value = true;

  try {
    // 添加用户消息
    const userMessage: ChatMessage = {
      role: "user",
      content: inputValue.value.trim(),
    };
    messageHistory.value.push(userMessage);

    // 添加AI消息，初始状态为思考中
    const aiMessage: ChatMessage = {
      role: "assistant",
      content: "",
      isThinking: true
    };
    messageHistory.value.push(aiMessage);
    scrollToBottom();

    const res = await fetch(
      `http://127.0.0.1:8888/chat?memoryId=${memoryId.value}&msg=${encodeURIComponent(inputValue.value.trim())}`,
      {
        method: "GET",
      }
    );
    inputValue.value = "";

    if (!res.body) {
      throw new Error("Response body is null");
    }

    const reader = res.body.getReader();
    const decoder = new TextDecoder("utf-8");
    let done = false;
    const aiResponseIndex = messageHistory.value.length - 1;

    // 开始接收响应后，取消思考状态
    messageHistory.value[aiResponseIndex].isThinking = false;

    while (!done) {
      const { value, done: readDone } = await reader.read();
      done = readDone;

      if (value) {
        const chunk = decoder.decode(value, { stream: true });
        messageHistory.value[aiResponseIndex].content += chunk;
        await nextTick();
      }
      scrollToBottom();
    }
  } catch (err) {
    console.error("请求失败:", err);
    messageHistory.value.pop();
    warning("无法获取AI响应，请稍后重试");
  } finally {
    isSending.value = false;
    scrollToBottom();
  }
}

// 滚动到底部的函数
function scrollToBottom() {
  const messageContainer = document.querySelector(".message-container");
  if (messageContainer) {
    messageContainer.scrollTop = messageContainer.scrollHeight;
  }
}
</script>

<template>

  <div class="chat-container">
    <div class="sidebar">
      <div style="display: flex;justify-content: center">
        <el-button type="success" round @click="" style="width: 200px;height: 50px">
          新建对话
          <el-icon class="plus-icon">
            <Plus/>
          </el-icon>
        </el-button>
      </div>
      <div class="sidebar-list">
        <div class="sidebar-title" v-for="m in 100">
          <span>我可以帮你写代码、读文件、写作各种创意内容，请把你的任务交给我吧~</span>
        </div>
      </div>
    </div>
    <div class="chat">
      <!-- 消息历史记录 -->
      <div class="message-container">
        <div v-for="(message, index) in messageHistory" :key="index" class="message-item">
          <div class="avatar">
            <img
              v-if="message.role === 'user'"
              src="../../../assets/images/my.jpg"
              alt="user"
              width="50px"
              style="border-radius: 50%"
            />
            <img
              v-else
              src="../../../assets/images/aipro.webp"
              width="50px"
              alt="ai"
              style="border-radius: 50%"
            />
          </div>
          <div class="content">
            <!-- 思考状态指示器 -->
            <div v-if="message.isThinking" class="thinking-indicator">
              <div class="dot"></div>
              <div class="dot"></div>
              <div class="dot"></div>
            </div>
            <div v-else v-html="marked(message.content)" class="markdown-content"></div>
          </div>
        </div>
        <div v-if="isShow === true" style="margin: 150px 0 0 -100px;">
          <div style="display: flex; justify-content: center; align-items: center; text-align: center;">
            <div style="display: flex; align-items: center; gap: 10px;">
              <img src="../../../assets/images/ai.svg" width="60">
              <h3 style="margin: 0;">我是 DeepSeek，很高兴见到你！</h3>
            </div>
          </div>
          <div style="text-align: center; margin-top: 20px;">
            我可以帮你写代码、读文件、写作各种创意内容，请把你的任务交给我吧~
          </div>
        </div>
      </div>

      <!-- 输入框和发送按钮 -->
      <div class="send-box">
      <textarea
        v-model="inputValue"
        placeholder="发送消息"
        rows="3"
        @keydown.enter.exact.prevent="sendMessage"
        @keydown.shift.enter.exact="inputValue += '\n'"
      ></textarea>
        <button :disabled="isSending" @click="sendMessage">
          {{ isSending ? "发送中..." : "发送" }}
        </button>
      </div>
      <div class="footer">
        <text>
          服务生成的所有内容均由人工智能模型生成，其生成内容的准确性和完整性无法保证，不代表我们的态度或观点
        </text>
      </div>
    </div>
  </div>

</template>

<style scoped>
.chat-container{
  height: calc(100vh - 10% - 90px);
}
.chat {
  display: flex;
  align-items: center;
  justify-items: center;
  flex-direction: column;
  height: calc(100vh - 10% - 90px);
  padding: 16px;
}
.sidebar{
  /*background-color: #2f74c4;*/
  width: 260px;
  border-right: 1px solid #e0e0e0;
  transition: all 0.3s ease;
  position: fixed;
  flex-direction: column;
  height: 750px;
  justify-items: center;
  align-items: center;
}

.sidebar-list{
  display: flex;
  flex-direction: column;
  overflow-y: scroll;
  justify-content: center;
  padding: 15px;
  width: 190px;
}
.sidebar-title{
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #ffffff;
  border-radius: 10px;
  padding: 0 10px;

}
.sidebar-title span{
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
  font-size: 15px;
  text-align: center;
}

.sidebar-title:hover{
    display: flex;
    background-color: #deeaf8;
    border-radius: 10px;
    color: #ffffff;
    transition: all 0.3s ease;
}

.message-container {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 16px;
}

.message-item {
  width: 950px;
  display: flex;
  align-items: flex-start;
  margin-bottom: 16px;
}

.avatar {
  margin-right: 12px;
}

.content {
  display: flex;
  justify-content: center;
  padding: 18px 0;
}

.content text{
  justify-content: center;
  align-items: center;
}

.send-box {
  display: flex;
  width: 1000px;
  gap: 8px;
  position: sticky;
  bottom: 0;
  background-color: white;
  padding: 16px 0;
  box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
}

textarea {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  resize: none;
  font-size: 20px;
}
textarea::placeholder {
  font-size: 20px;
  align-items: center;
}
textarea:focus {
  border-color: #409eff;
  outline: none;
  box-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
}

button {
  padding: 8px 16px;
  background-color: #007bff;
  color: white;
  border: none;
  width: 90px;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}

.footer {
  display: flex;
  justify-content: center;
  margin-top: auto;
}

.footer text {
  font-size: 9px;
  color: #bdbec1;
}
.message-container {
  width: 1000px;
  overflow-y: auto;
  margin-bottom: 16px;
  scroll-behavior: smooth;
}

/* 思考指示器样式 */
.thinking-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #888;
  animation: bounce 1.4s infinite ease-in-out;
}

.dot:nth-child(1) {
  animation-delay: -0.32s;
}

.dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  } 40% {
      transform: scale(1);
    }
}

/*.markdown-content {*/
/*  white-space: pre-wrap;*/
/*  word-wrap: break-word;*/
/*}*/
.markdown-content{
  font-size: 16px;
  /*padding: 14px;*/
}

.markdown-content h1, .markdown-content h2, .markdown-content h3 {
  color: #333;
}

.markdown-content code {
  background: #f4f4f4;
  padding: 2px 4px;
  border-radius: 4px;
}

.markdown-content pre {
  background-color: #2d2d2d;
  color: #fff;
  padding: 10px;
  overflow-x: auto;
}
</style>
